﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Xml;

namespace WeiXinPayClass
{
    
    /// <summary>
    /// 一缕晨光工作室 www.wispdawn.com
    /// </summary>
    public class WxPayHelper
    {
        public const string unifiedorderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";     
        public WxPayHelper()
        {
            this.parameters = new Dictionary<string, string>();
            this.returnParameter = new Dictionary<string, string>();
            //this.appid = "wxed94e6985d29****";//appid
            //this.mch_id = "122468****";      //微信支付商户号         
            //this.PartnerKey = "ASD2Ssaghh3df4570erdssd4we33****";//这里是商户的partnerkey  
            this.appid = "wx1696443fbd5c7d06";//appid
            this.mch_id = "1484582142";      //微信支付商户号         
            this.PartnerKey = "8310E36CAC2CCD8DC1A3ECFF6C92015A";//
        }

        #region 私有属性
        private string appid;
        private string mch_id; //商户号      
        private string PartnerKey;//商户密钥
        private Dictionary<string, string> parameters;
        private Dictionary<string, string> returnParameter;

        public string GetAppId
        {
            get { return appid; }
        }

        public string GetMch_Id
        {
            get { return mch_id; }
        }

        public string GetPartnerKey
        {
            get { return PartnerKey; }
        }

        #endregion

        /// 动态设置参数
        /// <summary>
        /// 动态设置参数
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value_ren"></param>
        public void SetParameter(string key, string value_ren)
        {
            parameters.Add(key, value_ren);
        }

        public void SetReturnParameter(string key, string value)
        {
            this.returnParameter.Add(key, value);
        }

        public Dictionary<string, string> GetParameter()
        {
            if (this.parameters!=null)
            {
                return this.parameters;
            }
            return null;
        }

        public string GetReturnXml()
        {
            this.returnParameter.Add("sign", GetSign(this.returnParameter));
            return CommonUtil.ArrayToXml(this.returnParameter);
        }



        /// 获得签名
        /// <summary>
        /// 获得签名
        /// </summary>
        /// <param name="paraDic"></param>
        /// <returns></returns>
        public string GetSign(Dictionary<string, string> paraDic)
        {
            Dictionary<string, string> bizParameters = new Dictionary<string, string>();          

            //转url格式
            string str = ToUrl(bizParameters);
            //在string后加入API KEY
            str += "&key=" + WxPayAPI.WxPayConfig.KEY;
            //MD5加密
            var md5 = MD5.Create();
            
            var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
            var sb = new StringBuilder();
            foreach (byte b in bs)
            {
                sb.Append(b.ToString("x2"));
            }
            //所有字符转为大写
            return sb.ToString().ToUpper();
        }

        public string ToUrl(Dictionary<string, string> m_values)
        {
            string buff = "";
            foreach (KeyValuePair<string, string> pair in m_values)
            {
                if (pair.Value == null)
                {

                }
                if (pair.Key != "sign" && pair.Value.ToString() != "")
                {
                    buff += pair.Key + "=" + pair.Value + "&";
                }
            }
            buff = buff.Trim('&');
            return buff;
        }

        public string MakePostXml()
        {          
            return CommonUtil.ArrayToXml(this.parameters);

        }

        /// 保存POST来的数据
        /// <summary>
        /// 保存POST来的数据
        /// </summary>
        /// <param name="xmlData"></param>
        public void ReceivePostXmlData(string xmlData)
        {           
            Dictionary<string, string> dic = CommonUtil.ReceivePostXmlData(xmlData);
            foreach (KeyValuePair<string,string> item in dic)
            {
                this.SetParameter(item.Key, item.Value);
            }
        }
       
        /// 验证签名
        /// <summary>
        /// 验证签名
        /// </summary>
        /// <returns></returns>
        public bool CheckSign()
        {
            Dictionary<string, string> dic = this.parameters;
            if (dic.Count>0)
            {
                string t = string.Empty;
                foreach (KeyValuePair<string,string> item in dic)
                {
                    t += item.Key + "=" + item.Value+"; ";
                }
                //logger.Info("this.parameters=" + t);
            }
            string postSign = string.Empty;
            if (dic.Keys.Contains("sign"))
            {
                postSign = dic["sign"];
                dic.Remove("sign");
            }           
            string sign = GetSign(dic);
            //logger.Info("重新生成sign=" + sign);         
            return postSign == sign;                 
        }

        

        /// 获取产品id
        /// <summary>
        /// 获取产品id
        /// </summary>
        /// <returns></returns>
        public string GetProductId()
        {
            if (this.parameters!=null&&this.parameters.Keys.Contains("product_id"))
            {
                return this.parameters["product_id"];   
            }
            return null;
        }

        /// 获取预payid
        /// <summary>
        /// 获取预payid
        /// </summary>
        /// <returns></returns>
        public string GetPrepayId()
        {
            this.parameters.Add("sign", GetSign(this.parameters));
            string xml=MakePostXml();         
            //logger.Info("请求PrepayId post 到微信的所有数据=" + xml);
            Dictionary<string, string> dic = HttpUtil.SendData(xml, unifiedorderURL);           
            //logger.Info("请求PrepayId 返回的 "+CommonUtil.ArrayToXml(dic));            
            if (dic != null && dic.Keys.Contains("prepay_id"))
            {
                return dic["prepay_id"];
            }
            return null;
        }



        #region 辅助方法

        


        /// 拼接成键值对
        /// <summary>
        /// 拼接成键值对
        /// </summary>
        /// <param name="paraMap"></param>
        /// <param name="urlencode"></param>
        /// <returns></returns>
        public static string FormatBizQueryParaMap(Dictionary<string, string> paraMap, bool urlencode)
        {
            string buff = "";
            try
            {             
                var result = from pair in paraMap orderby pair.Key select pair;
               
                foreach (KeyValuePair<string, string> pair in result)
                {
                    if (pair.Key != "")
                    {

                        string key = pair.Key;
                        string val = pair.Value;
                        if (urlencode)
                        {
                            val = System.Web.HttpUtility.UrlEncode(val);
                        }
                        buff += key.ToLower() + "=" + val + "&";

                    }
                }

                if (buff.Length == 0 == false)
                {
                    buff = buff.Substring(0, (buff.Length - 1) - (0));
                }
            }
            catch (Exception e)
            {
                //throw new SDKRuntimeException(e.Message);
            }
            return buff;
        }
           
        #endregion

    }
}
